package com.dfy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dfy.dto.LoginRequest;
import com.dfy.dto.LoginResponse;
import com.dfy.dto.RegisterRequest;
import com.dfy.dto.UpdateUserRequest;
import com.dfy.dto.SpotDTO;
import com.dfy.entity.User;
import com.dfy.entity.UserFavorite;
import com.dfy.entity.Spot;
import com.dfy.mapper.UserMapper;
import com.dfy.mapper.UserFavoriteMapper;
import com.dfy.mapper.SpotMapper;
import com.dfy.service.UserService;
import com.dfy.exception.BusinessException;
import com.dfy.util.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.beans.BeanUtils;
import com.dfy.service.UserFavoriteService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.HashMap;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserFavoriteMapper userFavoriteMapper;

    @Autowired
    private SpotMapper spotMapper;

    @Autowired
    private UserFavoriteService userFavoriteService;

    @Override
    @Transactional
    public User register(RegisterRequest request) {
        // 检查用户名是否已存在
        if (lambdaQuery().eq(User::getUsername, request.getUsername()).exists()) {
            throw new BusinessException(400, "用户名已存在");
        }

        // 检查邮箱是否已存在
        if (lambdaQuery().eq(User::getEmail, request.getEmail()).exists()) {
            throw new BusinessException(400, "邮箱已被注册");
        }

        // 检查手机号是否已存在
        if (lambdaQuery().eq(User::getPhone, request.getPhone()).exists()) {
            throw new BusinessException(400, "手机号已被注册");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setRole("USER");
        user.setStatus("ACTIVE");
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        user.setIsDeleted(false);

        // 保存用户
        save(user);
        
        return user;
    }

    @Override
    public LoginResponse login(LoginRequest request) {
        User user = userMapper.findByPhoneForLogin(request.getPhone());
                
        if (user == null) {
            throw new BusinessException(400, "手机号或密码错误");
        }

        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new BusinessException(400, "手机号或密码错误");
        }

        // 检查用户状态
        if (!"ACTIVE".equals(user.getStatus())) {
            throw new BusinessException(400, "账号已被禁用");
        }

        // 生成 token 前添加日志
        log.info("Generating token for user: {}, role: {}", user.getUsername(), user.getRole());
        
        log.info("User role before generating token: {}", user.getRole());
        // 确保角色名称不包含 ROLE_ 前缀，因为 JwtAuthenticationFilter 会添加
        String role = user.getRole().startsWith("ROLE_") ? 
            user.getRole().substring(5) : user.getRole();
        
        String token = jwtUtils.generateToken(
            user.getUsername(),
            user.getUserId(),
            role  // 使用处理后的角色
        );
        log.info("Generated token with role: {}", role);
        
        // 生成 token 后添加日志
        log.info("Token generated successfully");
        
        // 创建嵌套的 UserInfo 对象，包含更多用户信息
        LoginResponse.UserInfo userInfo = LoginResponse.UserInfo.builder()
                .userId(user.getUserId())
                .username(user.getUsername())
                .email(user.getEmail())      // 添加邮箱
                .phone(user.getPhone())      // 添加手机号
                .role(user.getRole())
                .build();
        
        // 构建完整的 LoginResponse
        return LoginResponse.builder()
                .token(token)
                .user(userInfo)
                .build();
    }

    @Override
    @Transactional
    public void updateUser(Long userId, UpdateUserRequest request) {
        // 获取用户
        User user = getById(userId);
        if (user == null) {
            throw new BusinessException(404, "用户不存在");
        }

        // 获取当前用户角色
        String currentUserRole = SecurityContextHolder.getContext()
                .getAuthentication()
                .getAuthorities()
                .stream()
                .findFirst()
                .map(a -> a.getAuthority())
                .orElse("");

        // 检查用户名是否已存在
        if (StringUtils.hasLength(request.getUsername()) 
                && !request.getUsername().equals(user.getUsername())) {
            boolean exists = lambdaQuery()
                    .eq(User::getUsername, request.getUsername())
                    .ne(User::getUserId, userId)
                    .exists();
            if (exists) {
                throw new BusinessException(400, "用户名已存在");
            }
            user.setUsername(request.getUsername());
        }

        // 检查邮箱是否已存在
        if (StringUtils.hasLength(request.getEmail()) 
                && !request.getEmail().equals(user.getEmail())) {
            boolean exists = lambdaQuery()
                    .eq(User::getEmail, request.getEmail())
                    .ne(User::getUserId, userId)
                    .exists();
            if (exists) {
                throw new BusinessException(400, "邮箱已被注册");
            }
            user.setEmail(request.getEmail());
        }

        // 检查手机号是否已存在
        if (StringUtils.hasLength(request.getPhone()) 
                && !request.getPhone().equals(user.getPhone())) {
            boolean exists = lambdaQuery()
                    .eq(User::getPhone, request.getPhone())
                    .ne(User::getUserId, userId)
                    .exists();
            if (exists) {
                throw new BusinessException(400, "手机号已被注册");
            }
            user.setPhone(request.getPhone());
        }

        // 如果要修改密码
        if (StringUtils.hasLength(request.getPassword())) {
            user.setPassword(passwordEncoder.encode(request.getPassword()));
        }

        // 如果要修改状态或角色，需要管理员权限
        if (!currentUserRole.equals("ROLE_ADMIN")) {
            if (StringUtils.hasLength(request.getStatus()) || StringUtils.hasLength(request.getRole())) {
                throw new BusinessException(403, "只有管理员可以修改用户状态和角色");
            }
        } else {
            // 管理员可以修改状态和角色
            if (StringUtils.hasLength(request.getStatus())) {
                user.setStatus(request.getStatus());
            }
            if (StringUtils.hasLength(request.getRole())) {
                user.setRole(request.getRole());
            }
        }

        // 更新时间
        user.setUpdatedAt(LocalDateTime.now());

        // 保存更新
        updateById(user);
    }

    @Override
    public boolean checkFavorite(Long userId, Long spotId) {
        // 使用 selectCount 替代 exists
        return userFavoriteMapper.selectCount(
            new LambdaQueryWrapper<UserFavorite>()
                .eq(UserFavorite::getUserId, userId)
                .eq(UserFavorite::getSpotId, spotId)
        ) > 0;
    }

    @Override
    @Transactional
    public void addFavorite(Long userId, Long spotId) {
        // 检查是否已收藏
        if (checkFavorite(userId, spotId)) {
            return;  // 已收藏则直接返回
        }

        // 创建收藏记录
        UserFavorite favorite = new UserFavorite();
        favorite.setUserId(userId);
        favorite.setSpotId(spotId);
        LocalDateTime now = LocalDateTime.now();
        favorite.setCreatedAt(now);
        favorite.setUpdatedAt(now);  // 设置更新时间
        userFavoriteMapper.insert(favorite);
    }

    @Override
    @Transactional
    public void removeFavorite(Long userId, Long spotId) {
        // 方式一：使用自定义方法
        userFavoriteMapper.deleteByUserIdAndSpotId(userId, spotId);
        
        // 或者方式二：使用 QueryWrapper
        /*
        LambdaQueryWrapper<UserFavorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserFavorite::getUserId, userId)
               .eq(UserFavorite::getSpotId, spotId);
        userFavoriteMapper.delete(wrapper);
        */
    }

    @Override
    public List<SpotDTO> getFavorites(Long userId) {
        // 直接调用 UserFavoriteService 的实现
        return userFavoriteService.getFavorites(userId);
    }
} 